package cn.ray_land.dlprint.data;

import android.os.Environment;
import android.support.annotation.NonNull;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static cn.ray_land.dlprint.util.Preconditions.checkNotNull;

/**
 * Created by gw on 2016/8/2.
 */

public class DiskSliceDataResource implements SliceDataResource {

    private static DiskSliceDataResource instance;

    public static DiskSliceDataResource getInstance(){
        if(instance == null){
            instance = new DiskSliceDataResource();
        }
        return instance;
    }

    private DiskSliceDataResource(){

    }

    @Override
    public void getDatas(@NonNull LoadDataCallback callback) {
        List<SliceData> datas = new ArrayList<>();
        getSliceDataFile("/storage/extsd", datas);
        getSliceDataFile("/storage/usbhost1", datas);
        getSliceDataFile(Environment.getExternalStorageDirectory().getAbsolutePath(), datas);

        if(datas.isEmpty()){
            callback.onDataNotAvailable();
        }else{
            callback.onDataLoaded(datas);
        }
    }

    @Override
    public void getData(@NonNull String dataPath, @NonNull GetDataCallback callback) {

    }

    @Override
    public void refreshDatas() {

    }

    @Override
    public void deleteAllDatas() {

    }

    @Override
    public void deleteData(@NonNull String dataPath) {
        File file = new File(dataPath);
        deleteFile(file);
    }

    private void getSliceDataFile(String absolutePath, List<SliceData> container) {
        final File path = new File(absolutePath);
        if(container == null) container = new ArrayList<>();
        FileFilter filter = new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory()||
                        pathname.getAbsolutePath().toLowerCase().endsWith(".slice");
            }
        };

        File[] files = path.listFiles(filter);
        if(files == null){
            return;
        }
        for(File f : files){
            if(f.isDirectory() && !f.getAbsolutePath().toLowerCase().endsWith(".slice")){
                getSliceDataFile(f.getAbsolutePath(), container);
            }
            if(f.isDirectory() && f.getAbsolutePath().toLowerCase().endsWith(".slice")){
                File[] gcodeFile = f.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.getName().toLowerCase().endsWith(".gcode");
                    }
                });
                if(gcodeFile.length == 1){
                    BufferedReader br = null;
                    try {
                        br = new BufferedReader(new FileReader(gcodeFile[0]));
                        String str;
                        while((str = br.readLine())!=null){
                            if(str.startsWith(";Number of Slices")){
                                int layers = Integer.parseInt(str.substring(str.lastIndexOf("=")+1).trim());
                                File[] imgFiles = f.listFiles(new FileFilter() {
                                    @Override
                                    public boolean accept(File pathname) {
                                        return pathname.getName().toLowerCase().endsWith(".png");
                                    }
                                });
                                if(layers == imgFiles.length){
                                    SliceData data = new SliceData(f, gcodeFile[0], layers);
                                    container.add(data);
                                }
                                break;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        if(br!=null){
                            try {
                                br.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
    }

    private void deleteFile(File file){
        checkNotNull(file);

        if(file.exists()){
            if(file.isFile()){
                file.delete();
            }
            if(file.isDirectory()){
                File[] subFiles = file.listFiles();
                for(File f : subFiles){
                   deleteFile(f);
                }
                file.delete();
            }
        }
    }
}
